package com.pinecone.service.impl;

import com.pinecone.common.Constant.RoleConstant;
import com.pinecone.common.exception.MinerException;
import com.pinecone.common.utils.JwtTokenUtil;
import com.pinecone.dao.SysUserRoleDao;
import com.pinecone.dto.UserDetailsDTO;
import com.pinecone.entity.SysRoleEntity;
import com.pinecone.entity.SysUserRoleEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.*;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Map;

import com.pinecone.dao.SysUserDao;
import com.pinecone.entity.SysUserEntity;
import com.pinecone.service.SysUserService;
import org.springframework.transaction.annotation.Transactional;


@Service("sysUserService")
public class SysUserServiceImpl implements SysUserService {
    protected static final Logger logger = LoggerFactory.getLogger(SysUserServiceImpl.class);
    @Autowired
    private JwtTokenUtil jwtTokenUtil;
    @Autowired
    AuthenticationManager myAuthenticationManager;
	@Autowired
	private SysUserDao sysUserDao;
    @Autowired
    private SysUserRoleDao sysUserRoleDao;
    @Autowired
    private UserDetailsServiceImpl userDetailsService;
	@Override
	public SysUserEntity queryObject(Integer userId){
		return sysUserDao.queryObject(userId);
	}
	
	@Override
	public List<SysUserEntity> queryList(Map<String, Object> map){
		return sysUserDao.queryList(map);
	}
	
	@Override
	public int queryTotal(Map<String, Object> map){
		return sysUserDao.queryTotal(map);
	}
	
	@Override
	public void save(SysUserEntity sysUser){
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        String rawPwd = sysUser.getPassword();
        //设置默认属性
        sysUser.setPassword(encoder.encode(rawPwd))
            .setLastPasswordResetDate(new Date())
            .setCreateTime(new Date())
            .setEnable(true);
		sysUserDao.save(sysUser);
		logger.info("系统用户注册成功:",sysUser);
	}
	
	@Override
	public void update(SysUserEntity sysUser){
		sysUserDao.update(sysUser);
	}
	
	@Override
	public void delete(Integer userId){
		sysUserDao.delete(userId);
	}
	
	@Override
	public void deleteBatch(Integer[] userIds){
		sysUserDao.deleteBatch(userIds);
	}
    /**
     * 注册系统用户
     * @param userEntity
     * @param roleId
     */
    @Transactional()
    public void registerSysUser(SysUserEntity userEntity, Integer roleId){
        save(userEntity);
        //保存用户角色对应关系
        SysUserRoleEntity userRoleEntity = new SysUserRoleEntity();
        userRoleEntity.setRoleId(roleId);
        userRoleEntity.setUserId(userEntity.getUserId());
        sysUserRoleDao.save(userRoleEntity);
    }
    /**
     *系统用户登录
     * @param username
     * @param password
     * @return
     */
    public String login(String username, String password){
        UsernamePasswordAuthenticationToken upToken = new UsernamePasswordAuthenticationToken(username+":"+ RoleConstant.SYSUSER, password);
        String token = "";
        try {
            //身份认证
            final Authentication authentication = myAuthenticationManager.authenticate(upToken);
            SecurityContextHolder.getContext().setAuthentication(authentication);
            final UserDetailsDTO userDetails = userDetailsService.loadUserByUsername(username+":"+ RoleConstant.SYSUSER);
            token = (jwtTokenUtil.generateToken(userDetails));

        } catch (UsernameNotFoundException e) {
            throw new MinerException("用户名或密码错误!",4001);
        } catch (LockedException e){
            throw new MinerException("用户已被锁定!",4002);
        } catch (InternalAuthenticationServiceException e){
            throw new MinerException("用户未被授予角色或权限!",4003);
        } catch (DisabledException e){
            throw new MinerException("用户不存在!",4004);
        }
        return token;
    }
	
}
